﻿using System;
using System.Collections.Generic;
using System.Linq;
using Xoohoo.Extensions;
using Xoohoo.Infrastructure;
using Xoohoo.Models;
using Xoohoo.Models.InputModels;
using Xoohoo.Repositories;

namespace Xoohoo.Services
{
    public class RoleService : IRoleService
    {
        private readonly IRoleRepository _repository;
        private readonly ICacheModule _cache;
        private readonly string _roleListCacheKey = "RoleList";

        public RoleService(IRoleRepository repository, IModuleRegistry modulesLoaded)
        {
            this._repository = repository;
            this._cache = modulesLoaded.GetModules<ICacheModule>().Last();
        }

        #region IRoleService Members

        public Role GetItem(Guid roleID)
        {
            return _repository.GetItem(roleID);
        }

        public Role GetItem(string roleName)
        {
            return _repository.GetItem(roleName);
        }

        public List<RoleBasic> GetList()
        {
            if (_cache != null)
            {
                var roles = _cache.GetItem<List<RoleBasic>>(
                    _roleListCacheKey, () => _repository.GetList(),
                    null
                    );
                return CloneRoles(roles);
            }
            else
            { 
                return _repository.GetList();
            }

        }

        public ModelResult Save(RoleInput roleInput)
        {
            ModelResult result = ValidateRole(roleInput);
            if (!result.IsValid) return result;
            _repository.Save(roleInput);
            _cache.Invalidate(_roleListCacheKey);
            return new ModelResult();

        }

        public bool Remove(Guid roleID)
        {
            bool result = _repository.Remove(roleID);
            if (result)
                _cache.Invalidate(_roleListCacheKey);
            return result;
        }

        public bool Move(Guid roleID, MovingTarget target)
        {
            bool result = _repository.Move(roleID, target);
            if(result)
                _cache.Invalidate(_roleListCacheKey);
            return result;
        }

        #endregion

        #region Private Methods
        /// <summary>
        /// 验证角色名称是否已经被使用
        /// </summary>
        /// <param name="roleID"></param>
        /// <param name="roleInput"></param>
        private ModelResult ValidateRole(RoleInput roleInput)
        {
            ModelResult modelResult = new ModelResult();
            Role foundRole;
            foundRole = _repository.GetItem(roleInput.RoleName);

            if (foundRole != null && roleInput.RoleID != foundRole.RoleID)
            {
                modelResult.Errors.Add("角色名称【" + roleInput.RoleName + "】已经被使用");
            }
            return modelResult;
        }

        private List<RoleBasic> CloneRoles(IEnumerable<RoleBasic> source)
        {
            if (source.IsNullOrEmpty())
                return new List<RoleBasic>();

            //深度克隆
            return (source.DeepClone() as IEnumerable<RoleBasic>).ToList();
            /*
            List<Role> roles = new List<Role>();
            foreach (var item in source)
            {
                roles.Add(new Role
                {
                    RoleID = item.RoleID,
                    RoleName = item.RoleName,
                    IsSystem = item.IsSystem,
                    DisplayOrder = item.DisplayOrder,
                    Permissions = item.Permissions == null ? Enumerable.Empty<PermissionBasic>() :
                       item.Permissions.Select(p => new PermissionBasic
                       {
                           PermissionID = p.PermissionID,
                           PermissionName = p.PermissionName,
                           ModuleName = p.ModuleName
                       })
                });
            }
            return roles;
            */
        }

        #endregion
    }
}
